<?php

class SqlProcessor {

    private $queryTemplate = array(
        'select' => 'SELECT @option: @fields: FROM @table: @cond: @group: @order: @limit:',
        'insert' => 'INSERT INTO @table: (@fields:) @values:',
        'delete' => 'DELETE FROM @table: @cond: @limit:',
        'update' => 'UPDATE @table: @set: @cond: @limit:',
        'native' => '@query:',
    );
    private $cond = array(
        -5 => 'NOT BETWEEN',
        -4 => 'NOT IN',
        -3 => 'NOT LIKE',
        -2 => '<',
        -1 => '<=',
        0 => '=',
        1 => '>=',
        2 => '>',
        3 => 'LIKE',
        4 => 'IN',
        5 => 'BETWEEN',
        6 => 'IS'
    );
    private $logic = array(
        -1 => "NOT",
        0 => "AND",
        1 => "OR"
    );

    public function __call($name, $arguments) {
        if (method_exists(__CLASS__, $name)) {
            return $this->$name($arguments);
        } else {
            return "/* " . __CLASS__ . "::$name */";
        }
    }

    function query($data) {
        return $data;
    }

    function action($data) {
        return $this->queryTemplate[$data];
    }

    function option($options) {
        return implode(' ', $options);
    }

    function limit($data) {
        return "limit " . implode(', ', $data);
    }

    function order($data) {
        $pieces = array();
        foreach ($data as $record) {
            $pieces[] = $record['field'] . " " . $record['direction'];
        }
        return "order by " . implode(', ', $pieces);
    }

    function values($values) {
        $pieces = array();

        foreach ($values as $record) {
            foreach ($record as $i => $rec) {
                if ($rec == "NULL()") {
                    $record[$i] = 'NULL';
                } elseif ($rec == "NOW()") {
                    $record[$i] = "'" . date('Y-m-d H:i:s') . "'";
                } elseif (is_numeric($rec)) {
                    $record[$i] = $rec;
                } elseif (is_string($rec)) {
                    $record[$i] = "'$rec'";
                } elseif ($rec == "") {
                    $record[$i] = "''";
                }
            }
            $pieces[] = "(" . implode(", ", $record) . ")";
        }
        return "VALUES " . implode(', ', $pieces);
    }

    function table($data) {
        $pieces = array();
        foreach ($data as $record) {
            $pieces[] = $record['table'] . ($record['alias'] ? " as " . $record['alias'] : false);
        }
        return implode(", ", $pieces);
    }

    function fields(&$data) {
        $pieces = array();
        foreach ($data as $record) {
            $pieces[] = $record['field'] . ($record['alias'] ? " as " . $record['alias'] : false);
        }
        return implode(", ", $pieces);
    }

    function cond($data) {
        $pieces = array();
        foreach ($data as $index => $params) {
            $params['logic'] = $index == 0 ? "WHERE" : $this->logic[$params['logic']];
            $params['value'] = ($params['noquotes'] || is_numeric($params['value'])) ? $params['value'] : "'" . $params['value'] . "'";
            if($params['value'] == "'NULL()'"){
                $params['value'] = "NULL";
            }elseif($params['value'] == "'NOW()'"){
                $params['value'] = date('Y-m-d H:i:s');
            }
            //d($params);
            $pieces[] = $params['logic'] . " " . $params['field'] . " " . $this->cond[$params['cond']] . " " . $params['value'];
            
        }        
        return implode(" ", $pieces);
    }

    function set($data) {
        $pieces = array();
        foreach ($data as $params) {
            $params['value'] = ($params['noquotes'] || is_numeric($params['value'])) ? $params['value'] : "'" . $params['value'] . "'";
            if ($params['value'] == "'NULL()'") {
                $params['value'] = 'NULL';
            } elseif ($params['value'] == "'NOW()'") {
                $params['value'] = "'" . date('Y-m-d H:i:s') . "'";
            }
            $pieces[] = $params['field'] . " = " . $params['value'];
        }
        return "SET " . implode(", ", $pieces);
    }

}
